/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.gmu.javalution.pfronts;

import java.util.Comparator;

/**
 *
 * @author jason.handuber
 */
public class EpsilonDoubleArrayComparator implements Comparator<double[]> {

    private final double epsilonTolerance;

    public EpsilonDoubleArrayComparator() {
        this.epsilonTolerance = 1E-10;
    }

    public EpsilonDoubleArrayComparator(double epsilonTolerance) {
        this.epsilonTolerance = epsilonTolerance;
    }

    public int compare(double[] a, double[] b) {
        assert (a.length == b.length);
        assert (a.length > 0);

        boolean aWins = false, bWins = false;
        for (int i = 0; i < a.length; i++) {
            //we assume minimization here, less is better
            if (a[i] + epsilonTolerance < b[i]) {
                aWins = true;
            }
            //we assume minimization here, less is better
            if (b[i] + epsilonTolerance < a[i]) {
                bWins = true;
            }
            if (aWins && bWins) {
                //since they both dominate eachother, they are incomparable
                return 0;
            }
        }

        if (aWins) {
            assert (!bWins);
            return -1;
        } else if (bWins) {
            assert (!aWins);
            return 1;
        } //extremely rare case: because of epsilon tolerance neither individual
        //ever beat the other
        else {
            return 0;
        }
//
//        int nfunc = a.length;
//
//        int m = 0;
//        int n = 0;
//
//        while (m < nfunc && a[m] <= b[m] + epsilonTolerance)
//        {
//            if (b[m] < a[m] + epsilonTolerance)
//            {
//                n++;
//            }
//
//            m++;
//        }
//
//        if (m == nfunc)
//        {
//            if (n == nfunc)
//            {
//                return 0;
//            }
//            else
//            {
//                return 1;
//            }
//        }
//
//        m = 0;
//        n = 0;
//        while (m < nfunc && b[m] <= a[m] + epsilonTolerance)
//        {
//            if (a[m] < b[m] + epsilonTolerance)
//            {
//                n++;
//            }
//
//            m++;
//        }
//
//        if (m == nfunc)
//        {
//            if (n != nfunc)
//            {
//                return -1;
//            }
//            else
//            {
//                return 0;
//            }
//        }
//
//        return 0;
    }
}
